

#include "sfc/serde.h"
#include "sfc/test.h"

namespace sfc::serde::json {

SFC_TEST(parse_null) {
  auto val = json::parse("null").unwrap();
  test::assert_true(val.as_null());
}

SFC_TEST(parse_bool) {
  {
    auto val = json::parse("true").unwrap();
    test::assert_eq(val.as_bool(), Option{true});
  }

  {
    auto val = json::parse("false").unwrap();
    test::assert_eq(val.as_bool(), Option{false});
  }
}

SFC_TEST(parse_int) {
  {
    auto val = json::parse("123").unwrap();
    test::assert_eq(val.as_int(), Option{123});
  }

  {
    auto val = json::parse("-123").unwrap();
    test::assert_eq(val.as_int(), Option{-123});
  }
}

SFC_TEST(parse_flt) {
  {
    auto val = json::parse("1.23").unwrap();
    test::assert_eq(val.as_flt(), Option{1.23});
  }

  {
    auto val = json::parse("-1.23").unwrap();
    test::assert_eq(val.as_flt(), Option{-1.23});
  }
}

SFC_TEST(parse_str) {
  {
    auto val = json::parse(R"("abc")").unwrap();
    test::assert_eq(val.as_str(), Option{"abc"});
  }
}

SFC_TEST(parse_list) {
  {
    auto val = json::parse("[]").unwrap();
    test::assert_true(val.as_list());
  }

  {
    auto val = json::parse("[ ]").unwrap();
    test::assert_true(val.as_list());
  }

  {
    auto val = json::parse("[\n]").unwrap();
    test::assert_true(val.as_list());
  }

  {
    auto val = json::parse("[ [] , [] ]").unwrap();
    test::assert_true(val.as_list());

    test::assert_true(val[0].as_list());
    test::assert_true(val[1].as_list());
  }

  {
    auto val = json::parse("[ [\n] , [\t[ ]\n] ]").unwrap();
    test::assert_true(val.as_list());

    test::assert_true(val[0].as_list());
    test::assert_true(val[1].as_list());
  }

  {
    auto val = json::parse("[ 1 ]").unwrap();
    test::assert_true(val.as_list());

    test::assert_eq(val.len(), 1U);
  }

  {
    auto val = json::parse("[ \n1 \n ]").unwrap();
    test::assert_true(val.as_list());
    test::assert_eq(val.len(), 1U);
  }

  {
    auto opt = json::parse("\n[ \n1, \n 2 \n ]");
    test::assert_true(opt);
    auto& val = *opt;

    test::assert_true(val.as_list());
    test::assert_eq(val.len(), 2U);
  }
}

SFC_TEST(parse_dict) {
  {
    auto val = json::parse("{}").unwrap();
    test::assert_true(val.as_dict());
    test::assert_eq(val.len(), 0U);
  }

  {
    auto val = json::parse("{  }").unwrap();
    test::assert_true(val.as_dict());
    test::assert_eq(val.len(), 0U);
  }

  {
    auto val = json::parse("{ \n }").unwrap();
    test::assert_true(val.as_dict());
    test::assert_eq(val.len(), 0U);
  }

  {
    auto val = json::parse(R"({ "a": 1 })").unwrap();
    test::assert_true(val.as_dict());
    test::assert_eq(val.len(), 1U);
    test::assert_eq(val["a"].as_int(), Option{1});
  }

  {
    auto val = json::parse(R"({"a":1, "b" : 2})").unwrap();
    test::assert_true(val.as_dict());
    test::assert_eq(val["a"].as_int(), Option{1});
    test::assert_eq(val["b"].as_int(), Option{2});
  }
}

}  // namespace sfc::serde::json
